package com.mashibing.serviceprice.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mashibing.serviceprice.dto.PriceRule;
import com.mashibing.serviceprice.mapper.PriceRuleMapper;
import com.mashibing.serviceprice.remote.ServiceMapClient;
import com.mashibing.serviceprice.service.ForecastPriceService;
import lombok.extern.slf4j.Slf4j;
import org.mashibing.constant.CommonStatusEnum;
import org.mashibing.dto.ResponseResult;
import org.mashibing.request.ForecastPriceDTO;
import org.mashibing.response.DirectionResponse;
import org.mashibing.response.ForecastPriceResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author:
 * @create: 2024/4/2 14:28
 * @description:
 */
@Service
@Slf4j
public class ForecastPriceServiceImpl implements ForecastPriceService {

    @Autowired
    ServiceMapClient serviceMapClient;
    @Autowired
    PriceRuleMapper priceRuleMapper;

    @Override
    public ResponseResult<ForecastPriceResponse> forecastPrice(String depLongitude,
                                                               String depLatitude,
                                                               String destLongitude,
                                                               String destLatitude,
                                                               String cityCode,
                                                               String vehicleType) {

        // 调用地图服务，查询距离和时长
        ForecastPriceDTO priceDTO = new ForecastPriceDTO(depLongitude,depLatitude,destLongitude,destLatitude,cityCode,vehicleType);
        ResponseResult<DirectionResponse> driving = serviceMapClient.driving(priceDTO);
        Integer distance = driving.getData().getDistance();
        Integer duration = driving.getData().getDuration();
        log.info("距离：{}",distance);
        log.info("时间：{}",duration);

        // 读取计价规则
        QueryWrapper<PriceRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("city_code",cityCode);
        queryWrapper.eq("vehicle_type",vehicleType);
        queryWrapper.orderByDesc("fare_version");

        List<PriceRule> priceRules = priceRuleMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(priceRules)) {
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_EMPTY.getCode(),CommonStatusEnum.PRICE_RULE_EMPTY.getValue());
        }
        PriceRule priceRule = priceRules.get(0);
        // 根据距离、时长、计价规则，计算价格
        BigDecimal price = getPrice(distance, duration, priceRule);
        ForecastPriceResponse priceResponse = new ForecastPriceResponse();
        priceResponse.setPrice(price.doubleValue());
        priceResponse.setCityCode(cityCode);
        priceResponse.setVehicleType(vehicleType);
        priceResponse.setFareType(priceRule.getFareType());
        priceResponse.setFareVersion(priceRule.getFareVersion());

        return ResponseResult.success(priceResponse);
    }

    /**
     * 计算价格
     * @param distance 距离
     * @param duration 时长
     * @param priceRule 计价规则
     * @return 价格
     */
    private BigDecimal getPrice(Integer distance, Integer duration, PriceRule priceRule){
        BigDecimal price = new BigDecimal(0);
        // 1.起步价
        BigDecimal startFare = priceRule.getStartFare();
        price = price.add(startFare);

        // 2.里程费
        // 总里程：m -> km
        BigDecimal distanceM = new BigDecimal(distance);
        BigDecimal distanceKm = distanceM.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
        // 起步里程：km
        BigDecimal startMile = new BigDecimal(priceRule.getStartMile());
        BigDecimal distanceSubtract = distanceKm.subtract(startMile);
        int compareTo = distanceSubtract.compareTo(BigDecimal.ZERO);
        distanceSubtract = compareTo < 0 ? BigDecimal.ZERO : distanceSubtract;
        // 计算里程价
        BigDecimal unitPricePerMile = priceRule.getUnitPricePerMile();
        BigDecimal mailFare = distanceSubtract.multiply(unitPricePerMile).setScale(2, RoundingMode.HALF_UP);
        price = price.add(mailFare);

        // 3.时长费
        // 时长：s -> m
        BigDecimal durationMinute = new BigDecimal(duration).divide(BigDecimal.valueOf(60), 2, RoundingMode.UP);
        BigDecimal pricePerMinute = priceRule.getUnitPricePerMinute();
        BigDecimal timeFare = durationMinute.multiply(pricePerMinute).setScale(2, RoundingMode.HALF_UP);
        price = price.add(timeFare);
        return price;
    }

}
